package com.zxjbyte.yiyi.framework.common.domain.api;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author zhangxingjia
 * @Date 2023/3/15 16:33
 * @Version: 1.0
 */
@Getter
@Setter
@ToString
@Schema(description = "分页返回信息")
public class PageResult<T> implements Serializable {

    private static final long serialVersionUID = -4777214261241850787L;

    @Schema(description = "状态码", requiredMode = Schema.RequiredMode.REQUIRED)
    private int code;

    @Schema(description = "是否成功", requiredMode = Schema.RequiredMode.REQUIRED)
    private boolean success;

    @Schema(description = "返回消息", requiredMode = Schema.RequiredMode.REQUIRED)
    private String msg;

    @Schema(description = "当前页", requiredMode = Schema.RequiredMode.REQUIRED)
    private int pageNo;

    @Schema(description = "页大小", requiredMode = Schema.RequiredMode.REQUIRED)
    private int pageSize;

    @Schema(description = "总页数", requiredMode = Schema.RequiredMode.REQUIRED)
    private int totalPage;

    @Schema(description = "总记录数", requiredMode = Schema.RequiredMode.REQUIRED)
    private long total;

    @Schema(description = "分页承载数据")
    private List<T> records;

    public PageResult(int pageNo, int pageSize){
        this.pageNo = Math.max(PageQuery.DEFAULT_PAGE_NO, pageNo);
        this.pageSize = pageSize <= 0 ? PageQuery.DEFAULT_PAGE_SIZE : pageSize;
    }

    public PageResult(int pageNo, int pageSize, IResultCode resultCode){
        this(pageNo, pageSize, resultCode, resultCode.getMessage());
    }

    public PageResult(int pageNo, int pageSize, IResultCode resultCode, String msg){
        this(pageNo, pageSize);
        this.code = resultCode.getCode();
        this.msg = msg;
        this.success = ResultCode.SUCCESS.code == code;
    }

    /**
     * mybatis plus分页模型转化
     * @param page
     * @param <T>
     * @return
     */
    public static <T> PageResult<T> of(IPage<T> page) {
        PageResult<T> pageResult = new PageResult<T>((int)page.getCurrent(), (int)page.getSize(), ResultCode.SUCCESS);
        pageResult.setRecords(page.getRecords());
        pageResult.setTotal(page.getTotal());
        pageResult.setTotalPage(totalPage(pageResult.getTotal(), pageResult.getPageSize()));
        return pageResult;
    }

    public static <T> PageResult<T> of(List<T> records, int pageNo, int pageSize, long total) {
        PageResult<T> pageResult = new PageResult<T>(pageNo, pageSize, ResultCode.SUCCESS);
        pageResult.setRecords(records);
        pageResult.setTotal(total);
        pageResult.setTotalPage(totalPage(pageResult.getTotal(), pageResult.getPageSize()));
        return pageResult;
    }

    public static <T> PageResult<T> of(List<T> records, IPage<?> page) {
        PageResult<T> pageResult = new PageResult<T>((int)page.getCurrent(), (int)page.getSize(), ResultCode.SUCCESS);
        pageResult.setRecords(records);
        pageResult.setTotal(page.getTotal());
        pageResult.setTotalPage(totalPage(pageResult.getTotal(), pageResult.getPageSize()));
        return pageResult;
    }

    public static <T> PageResult<T> emptyOf(int pageNo, int pageSize) {
        return of(new ArrayList<>(), pageNo, pageSize, 0L);
    }

    private static int totalPage(long total, int pageSize){
        return Math.toIntExact(total % pageSize == 0 ? (total / pageSize) : (total / pageSize + 1));
    }
}
